﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
using Tool;
using static Microsoft.AspNetCore.Hosting.Internal.HostingApplication;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;

namespace MyMusicList.Controllers.Tool
{
    [Route("api/[controller]")]
    [ApiController]
    public class FilesController : ApiController
    {
        /// <summary>
        /// 上传文件(单一大文件分段传输)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [DisableRequestSizeLimit]
        public async Task<ActionResult> UploadFile()
        {
            var data = Request.Form.Files["data"];
            string lastModified = Request.Form["lastModified"].ToString();
            var total = Request.Form["total"];
            var fileName = Request.Form["fileName"];
            var index = Request.Form["index"];

            string rootdir = AppContext.BaseDirectory;
            DirectoryInfo Dir = Directory.GetParent(rootdir);
            string root = Dir.FullName;

            string temporary = Path.Combine(root+"/wwwroot/", lastModified);//临时保存分块的目录
            try
            {
                if (!Directory.Exists(temporary))
                    Directory.CreateDirectory(temporary);
                string filePath = Path.Combine(temporary, index.ToString());
                if (!Convert.IsDBNull(data))
                {
                    await Task.Run(() => {
                        FileStream fs = new FileStream(filePath, FileMode.Create);
                        data.CopyTo(fs);
                        fs.Close();
                    });
                }
                bool mergeOk = false;
                string fileNameStr = "";
                string finalPathStr="";
                if (total == index)
                {
                   var ul =  await FileMerge(lastModified, fileName);
                    mergeOk = ul.mergeOk;
                    fileNameStr = ul.filename;
                    finalPathStr = ul.finalPath;
                }

                

                Dictionary<string, object> result = new Dictionary<string, object>();
                result.Add("number", index);
                result.Add("mergeOk", mergeOk);
                result.Add("fileName", fileNameStr);
                result.Add("finalPathStr", finalPathStr);
                result.Add("root", root);
                JsonResult jsonResult = new JsonResult(result);

                return jsonResult;
            }
            catch (Exception ex)
            {
                Directory.Delete(temporary);//删除文件夹
                throw ex;
            }

        }

        public async Task<UpLoad> FileMerge(string lastModified, string fileName)
        {
            UpLoad ul = new UpLoad();
            string filename ;
            string finalPath;
            bool ok = false;
            try
            {
                string rootdir = AppContext.BaseDirectory;
                DirectoryInfo Dir = Directory.GetParent(rootdir);
                string root = Dir.FullName;

                var temporary = Path.Combine(root+"/wwwroot/", lastModified);//临时文件夹
                fileName = Request.Form["fileName"];//文件名
                string fileExt = Path.GetExtension(fileName);//获取文件后缀
                var files = Directory.GetFiles(temporary);//获得下面的所有文件
                filename = DateTime.Now.ToString("yyMMddHHmmss") + fileExt;
                 finalPath = Path.Combine(root + "/wwwroot/", filename);//最终的文件名（demo中保存的是它上传时候的文件名，实际操作肯定不能这样）
                var fs = new FileStream(finalPath, FileMode.Create);
                foreach (var part in files.OrderBy(x => x.Length).ThenBy(x => x))//排一下序，保证从0-N Write
                {
                    var bytes = System.IO.File.ReadAllBytes(part);
                    await fs.WriteAsync(bytes, 0, bytes.Length);
                    bytes = null;
                    System.IO.File.Delete(part);//删除分块
                }
                fs.Close();
                Directory.Delete(temporary);//删除文件夹
                ok = true;
            }
            catch (Exception ex)
            {
                throw ex;
            }

            ul.mergeOk = ok;
            ul.filename = filename;
            ul.finalPath = finalPath;
            return ul;
        }

        [HttpGet]
        public IActionResult DownLoadFile(string url)
        {
            try
            {
                string rootdir = AppContext.BaseDirectory;
                DirectoryInfo Dir = Directory.GetParent(rootdir);
                string root = Dir.FullName;

                var stream = System.IO.File.OpenRead(root + "/wwwroot/"+url);
                //var stream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);//推荐此方法
                string fileExt = Path.GetExtension(root + "/wwwroot/"+url);
                //获取文件的ContentType
                var provider = new FileExtensionContentTypeProvider();
                var memi = provider.Mappings[fileExt];
                return File(stream, memi, Path.GetFileName(root + "/wwwroot/"+url));
            }
            catch (Exception ex)
            {
                return NotFound();
            }
        }

    }


    public class UpLoad
    {
        public bool mergeOk { set; get; }

        public string filename { set; get; }

        public string finalPath { set; get; }
    }
}